"""
使用场景：在使用迷宫生成和BOSS生成之后，进入游戏核心
先是迷宫场景，在迷宫场景中碰到BOSS之后进入BOSS场景
需要将迷宫获得的道具带入BOSS界面
"""
import sys
import time
import pygame
from config import *

from visualizer import MazeVisualizer
from greedy_planner import GreedyPlanner
from dp_planner_Dijkstra import DPPlannerDijkstra
from lockvisualizer import LockVisualizer
from bossbattle import BossBattle

class GameCore:
    def __init__(self, maze_visualizer:MazeVisualizer, difficulty, mode):
        """
        :param maze_visualizer: 迷宫的可视化
        """
        # maze_grid 是 List 所以二者会同步更新，
        self.maze_grid = maze_visualizer.maze_grid
        self.maze_visualizer = maze_visualizer
        self.size = MAZE_N_DIFFICULTY if difficulty == 1 else MAZE_N_SIMPLE
        self.mode = mode
        # 规划器
        self.help_greedy_planner = GreedyPlanner(maze_grid=self.maze_grid)
        # 迷宫部分参数
        start_pos = self.help_greedy_planner.find_start()

        self.player_pos = start_pos
        self.player_scores = 0 # 分数
        self.game_over = False
        self.game_won = False

        # 状态管理
        self.visited = {start_pos}
        self.path_history = [start_pos]
        self.highlighted_path = []

        # 动态规划部分：
        planner = DPPlannerDijkstra(self.maze_grid)
        self.dp_track_list, self.dp_score = planner.calculate_optimal_path()
        self.dp_pointer = 0

        # 机关锁解密界面
        self.locker_active = False  # 机关锁是否激活

    def move_player_in_maze(self, dr, dc):
        """
        在迷宫中移动玩家，并维护记忆化
        这里包含迷宫中移动之后的效果逻辑
        :param dr: 移动的目标行
        :param dc: 移动的目标列
        """
        if self.game_over or self.game_won: return

        new_r, new_c = self.player_pos[0] + dr, self.player_pos[1] + dc

        target_cell = self.maze_grid[new_r, new_c]
        target_pos = (new_r, new_c)

        # 撞墙
        if target_cell == WALL:
            """
            这里是撞墙逻辑编写
            撞墙会移动失败，所以最后直接return
            可以插入效果音或者特效（待做）
            """
            print("你撞墙啦")
            return
        
        # 到这里说明可以移动到这里
        # 维护记忆化
        self.player_pos = target_pos
        is_backtracking=False

        if len(self.path_history) >= 2 and target_pos == self.path_history[-2]: is_backtracking=True
        if is_backtracking:
            self.path_history.pop()
        else:
            self.path_history.append(target_pos)
        self.visited.add(target_pos)

        # 获得金币
        if target_cell == GOLD:
            self.player_scores += 5
            print("获得金币")
            self.maze_grid[new_r, new_c] = PATH
        # 踩到陷阱
        elif target_cell == TRAP:

            self.player_scores -= 3
            print("踩到陷阱")
            self.maze_grid[new_r, new_c] = PATH
        # 出口和锁，这里没有解不开锁退出的选项
        elif target_cell == EXIT:
            self.lock_visualizer = LockVisualizer()
            self.locker_active = True  # 激活机关锁状态
            self.lock_visualizer.activate()  # 激活机关锁界面
            # self.game_over = True
            # self.player_scores += 10
            # print(f"到达终点, 您的得分是{self.player_scores}")
        elif target_cell == BOSS:
             # 将当前迷宫得分作为资源传递给BOSS战斗
            boss_battle = BossBattle(resources_from_maze=self.player_scores)
            # 开始BOSS战斗，获取BOSS战斗得分
            boss_score = boss_battle.start_battle()
            # 将BOSS战斗得分加入到玩家总分数中
            if boss_score > 0:
                self.player_scores += boss_score
                print(f"BOSS战斗胜利！获得分数: {boss_score}")
                print(f"当前总分: {self.player_scores}")
                # 将BOSS格子变为普通路径
                self.maze_grid[new_r, new_c] = PATH
            else: print("BOSS战斗失败！")
            # 返回迷宫界面，维护屏幕尺寸
            self.maze_visualizer.recover_size()

        return # 礼貌性的return一下

    def event_handle(self, event, mode):
        # 顶层优先：处理机关锁
        if self.locker_active:
            lock_result = self.lock_visualizer.handle_event(event)
            if lock_result == "SUCCESS":
                # 解锁成功，将机关锁位置变为路径
                self.locker_active = False  # 解除机关锁状态
                self.lock_visualizer.deactivate()
                self.game_over = True
            # 跳过其他事件处理
            return
        # 人类：键盘控制
        if mode == HUMANITY:
            if event.type == pygame.KEYDOWN:
                # 人物移动：陷阱我看见了不能躲吗？！——摩尔邻域有感
                if event.key == pygame.K_KP8:
                    self.move_player_in_maze(-1, 0)
                elif event.key == pygame.K_KP2:
                    self.move_player_in_maze(1, 0)
                elif event.key == pygame.K_KP4:
                    self.move_player_in_maze(0, -1)
                elif event.key == pygame.K_KP6:
                    self.move_player_in_maze(0, 1)
                elif event.key == pygame.K_KP7:
                    self.move_player_in_maze(-1, -1)
                elif event.key == pygame.K_KP9:
                    self.move_player_in_maze(-1, 1)
                elif event.key == pygame.K_KP1:
                    self.move_player_in_maze(1, -1)
                elif event.key == pygame.K_KP3:
                    self.move_player_in_maze(1, 1)
                # 键盘功能部分
                # d 调试键盘输入
                elif event.key == pygame.K_d:
                    print("asdf")
                # t 贪心提示
                elif event.key == pygame.K_t:
                    # 测试用的贪心帮助策略
                    # ￥ 应该增加移动之后提示消失逻辑
                    target_pos = self.help_greedy_planner.get_next_move(
                        current_pos=self.player_pos,
                        visited=self.visited,
                        path_history=self.path_history
                    )
                    if target_pos:
                        print(f"Greedy Suggestion: From {self.player_pos} Move to {target_pos}")
                        self.highlighted_path = [target_pos]
                elif event.key == pygame.K_s:
                    if self.dp_track_list:
                        print(f"dp Suggestion: From the Start Move to the Final, and you'll get {self.dp_score} points")
                        self.highlighted_path = self.dp_track_list

    def AI_greedy_mode(self):
        target_pos = self.help_greedy_planner.get_next_move(
            current_pos=self.player_pos,
            visited=self.visited,
            path_history=self.path_history
        )
        target_cell = self.maze_grid[target_pos[0], target_pos[1]]
        if target_cell != EXIT:
            self.move_player_in_maze(target_pos[0] - self.player_pos[0], target_pos[1] - self.player_pos[1])
        else:
            self.game_over = True
        pygame.time.wait(200)  # 减慢速度

    def AI_dp_mode(self):
        if self.locker_active: return  # 防止没结束往下访问导致越界
        target_pos = self.dp_track_list[self.dp_pointer]
        self.dp_pointer = self.dp_pointer + 1
        self.move_player_in_maze(target_pos[0] - self.player_pos[0], target_pos[1] - self.player_pos[1])
        pygame.time.wait(200)  # 减慢速度

    def run(self):
        """
        整体逻辑：调用生成的迷宫界面，
        """
        self.maze_visualizer.draw_maze()
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                    sys.exit()
                self.event_handle(event, self.mode)

            # 进入贪心Ai，成功
            if self.mode == AI_GREEDY and not (self.game_over or self.game_won):
                self.AI_greedy_mode()
            # 进入动态规划AI，成功
            if self.mode == AI_DP and not (self.game_over or self.game_won):
                self.AI_dp_mode()

            # 游戏结束
            if self.game_won or self.game_over:
                print("游戏结束")
                if self.game_won:
                    print(f"最终得分: {self.player_scores}")
                time.sleep(3)
                running = False

            # 显示更新策略
            self.update_display_maze()

    def update_display_maze(self):
        # 1. 迷宫
        self.maze_visualizer.draw_maze()
        # 2. 高亮
        self.maze_visualizer.draw_path(self.highlighted_path, COLOR_GOLD)
        # 3. 人物
        if not self.game_over:
            self.maze_visualizer.draw_player(self.player_pos)
        # 4. 机关锁
        if self.locker_active:
            self.lock_visualizer.draw()
        # 5. 屏幕刷新
        self.maze_visualizer.update_display()
